package com.blockmeta.bbs.businesslibrary.service;

import android.app.IntentService;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import androidx.core.app.NotificationCompat;
import com.blankj.utilcode.util.LogUtils;

import com.blockmeta.bbs.baselibrary.base.app.BaseApp;
import com.blockmeta.bbs.baselibrary.utils.SharedPreferenceUtil;
import com.blockmeta.bbs.businesslibrary.constant.Constant;
import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadListener;
import com.liulishuo.filedownloader.FileDownloader;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;


public class DownloadService extends IntentService {
    private static final int BUFFER_SIZE = 16 * 1024; // 8k ~ 32K
    private static final String TAG = "DownloadService";
    public static final String MY_CHANNEL_01 = "my_channel_01";
    private NotificationManager mNotifyManager;
    private NotificationCompat.Builder mBuilder;

    private RandomAccessFile m_ApkFile;

    private String m_FileName;

    private long startPosition;

    private String downloadUrl;

    private long fileSize;

    private String fileName;

    private long completeSize;

    private boolean isAutoDownload;

    private DownloadBinder binder = new DownloadBinder();

    private DownloadCallback mCallBack;// The user-visible name of the channel.
    public static final CharSequence CHANNEL_NAME = "8btc";

    public DownloadService() {
        super("DownloadService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            int importance = NotificationManager.IMPORTANCE_LOW;
            NotificationChannel mChannel = new NotificationChannel(MY_CHANNEL_01, CHANNEL_NAME, importance);
            mChannel.setSound(null, null);
            mNotifyManager.createNotificationChannel(mChannel);
        }
        mBuilder = new NotificationCompat.Builder(this, MY_CHANNEL_01);
        String appName = getString(getApplicationInfo().labelRes);
        int icon = getApplicationInfo().icon;
        mBuilder.setContentTitle(appName).setSmallIcon(icon);
        mBuilder.setOnlyAlertOnce(true);

        downloadUrl = intent.getStringExtra(Constant.APK_FILE_URL);
        m_FileName = intent.getStringExtra(Constant.APK_FILE_PATH);
        fileName = intent.getStringExtra(Constant.APK_FILE_NAME);
        isAutoDownload = intent.getBooleanExtra(Constant.APK_FILE_IS_AUTO, false);

        getFileLength();
        URL url;

        if (fileSize <= 0) {
            //("网络故障,无法获取文件大小");
            return;
        }

        if (!isFirstDownload()) {
//            init();
        } else {
            startPosition = SharedPreferenceUtil.getLong(BaseApp.getApp(), Constant.KEY_DOWN_SIZE, 0);
            if(startPosition > fileSize)
            {
                startPosition = 0;
//                init();
            }
            completeSize = startPosition;
        }
        FileDownloader.setup(DownloadService.this);
        File file = new File(m_FileName);
        LogUtils.i("downloadapk", file.getAbsolutePath());
        FileDownloader.getImpl().create(downloadUrl)
                .setAutoRetryTimes(1)
                .setPath(m_FileName)
                .setListener(new FileDownloadListener() {
                    @Override
                    protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                    }

                    @Override
                    protected void started(BaseDownloadTask task) {
                    }

                    @Override
                    protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
                    }

                    @Override
                    protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                        updateProgress((int) (soFarBytes * 100L / totalBytes));
                    }

                    @Override
                    protected void blockComplete(BaseDownloadTask task) {
                    }

                    @Override
                    protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
                    }

                    @Override
                    protected void completed(BaseDownloadTask task) {
                        downloadFinish(true);
                    }

                    @Override
                    protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                    }

                    @Override
                    protected void error(BaseDownloadTask task, Throwable e) {
                        downloadFinish(false);
                    }

                    @Override
                    protected void warn(BaseDownloadTask task) {
                    }
                }).start();
//        HttpURLConnection urlConnection = null;
//        RandomAccessFile randomAccessFile = null;
//        InputStream is = null;
//        try {
//            url = new URL(downloadUrl);
//            urlConnection = (HttpURLConnection) url.openConnection();
//            urlConnection.setRequestProperty("Range", "bytes=" + startPosition + "-");
//            urlConnection.setRequestMethod("GET");
//            urlConnection.setDoOutput(false);
//            urlConnection.setConnectTimeout(10 * 1000);
//            urlConnection.setReadTimeout(10 * 1000);
//            urlConnection.setRequestProperty("Connection", "Keep-Alive");
//            urlConnection.setRequestProperty("Charset", "UTF-8");
//            urlConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");
//
//            randomAccessFile = new RandomAccessFile(new File(m_FileName), "rwd");
//            randomAccessFile.seek(startPosition);
//
//            urlConnection.connect();
//            if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL) {
//                is = urlConnection.getInputStream();
//                byte[] buffer = new byte[BUFFER_SIZE];
//                int length = -1;
//                int oldProgress = (int) (completeSize * 100 / fileSize);
//                while ((length = is.read(buffer)) != -1) {
//                    randomAccessFile.write(buffer, 0, length);
//                    completeSize += length;
//                    int progress = (int) (completeSize * 100L / fileSize);
//                    if (progress != oldProgress) {
//                        updateProgress(progress);
//                    }
//                    SharedPreferenceUtil.putLong(BaseApp.getApp(), Constant.KEY_DOWN_SIZE, completeSize);
//                }
//                downloadFinish(true);
//            }
//        } catch (Exception e) {
//            SharedPreferenceUtil.putLong(BaseApp.getApp(), Constant.KEY_DOWN_SIZE, completeSize);
//            downloadFinish(false);
//        } finally {
//            try {
//                is.close();
//                randomAccessFile.close();
//                urlConnection.disconnect();
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
    }

    private void getFileLength() {
        HttpURLConnection conn = null;
        RandomAccessFile randomFile = null;
        URL url = null;
        try {
            url = new URL(downloadUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5 * 1000);
            conn.setRequestMethod("GET");
            // 如果http返回的代码是200或者206则为连接成功
            if (conn.getResponseCode() == 200 || conn.getResponseCode() == 206)  //状态码(206)，表示服务器已经执行完部分对资源的GET请求
            {
                fileSize = conn.getContentLength();// 得到文件的大小

                conn.disconnect();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    public class DownloadBinder extends Binder {
        /**
         * 开始下载
         *
         * @param callback  下载回调
         */
        public void start(DownloadCallback callback) {
            //下载
            mCallBack = callback;
            if(callback != null) {
                mCallBack.onStart();
            }
        }

        public void stop(String msg) {
//            DownloadService.this.stop(msg);
        }
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // 返回自定义的DownloadBinder实例
        return binder;
    }

    private void updateProgress(int progress) {
        if (isAutoDownload)
            return;

        mBuilder.setContentText("").setProgress(100, progress, false);
        mNotifyManager.notify(0, mBuilder.build());
        if (mCallBack != null) {
            mCallBack.onProgress(progress, 100);
        }
        if (progress == 100)
            mNotifyManager.cancel(0);
    }

    public static boolean createFile(String destFileName) {
        File file = new File(destFileName);
        if (file.exists()) {
            return false;
        }
        if (destFileName.endsWith(File.separator)) {
            return false;
        }
        //判断目标文件所在的目录是否存在
        if (!file.getParentFile().exists()) {
            if (!file.getParentFile().mkdirs()) {
                return false;
            }
        }
        //创建目标文件
        try {
            if (file.createNewFile()) {
                return true;
            } else {
                System.out.println("创建单个文件" + destFileName + "失败！");
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    private void initFirst() {
        try {
            if (createFile(m_FileName)) {
                File mFile = new File(m_FileName);
                RandomAccessFile accessFile = new RandomAccessFile(mFile, "rwd");
                accessFile.setLength(fileSize);
                accessFile.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void init() {
        try {
            if (createFile(m_FileName)) {
                File mFile = new File(m_FileName);
                RandomAccessFile accessFile = new RandomAccessFile(mFile, "rwd");
                accessFile.setLength(fileSize);
                accessFile.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private boolean isFirstDownload() {
        return new File(m_FileName).exists();
    }

    private void downloadFinish(boolean isLoadSuccess) {

        if (isLoadSuccess) {
            File file = new File(m_FileName);
            file.renameTo(new File(m_FileName + ".apk"));
            SharedPreferenceUtil.remove(BaseApp.getApp(), Constant.KEY_DOWN_SIZE);
        }
        Intent intent = new Intent(Constant.DOWN_LOAD_ACTION);
        intent.putExtra(Constant.APK_FILE_PATH, m_FileName + (isLoadSuccess ? ".apk" : ""));
//		intent.putExtra(Constant.APK_FILE_IS_AUTO, isAutoDownload);
        intent.putExtra(Constant.APK_FILE_IS_LOAD_SUCCESS, isLoadSuccess);
        intent.putExtra(Constant.APK_FILE_URL, downloadUrl);
//		intent.putExtra(Constant.APK_FILE_SIZE, fileSize);
        intent.putExtra(Constant.APK_FILE_NAME, fileName);
        sendBroadcast(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public static void bindService(Context context, ServiceConnection connection) {
        Intent intent = new Intent();
        String fileName = "8btc";
        intent.setClass(context, DownloadService.class);
        intent.putExtra(Constant.APK_FILE_URL, SharedPreferenceUtil.getString(BaseApp.getApp(), Constant.UPDATE_URL, null));
        intent.putExtra(Constant.APK_FILE_NAME, fileName);
        intent.putExtra(Constant.APK_FILE_PATH, getFilePath() + File.separator + fileName);
        context.startService(intent);
        context.bindService(intent, connection, Context.BIND_AUTO_CREATE);
    }

    public static String getFilePath() {
        return Environment.getExternalStorageDirectory().getAbsolutePath() +
                File.separator;
    }
    /**
     * 进度条回调接口
     */
    public interface DownloadCallback {
        /**
         * 开始
         */
        void onStart();

        /**
         * 进度
         *
         * @param progress  进度 0.00 -1.00 ，总大小
         * @param totalSize 总大小 单位B
         */
        void onProgress(int progress, int totalSize);

        boolean onFinish(File file);

        /**
         * 下载异常
         *
         * @param msg 异常信息
         */
        void onError(String msg);

        /**
         * 当应用处于前台，准备执行安装程序时候的回调，
         *
         * @param file 当前安装包
         * @return false 默认 false ,当返回时 true 时，需要自己处理 ，前提条件是 onFinish 返回 false 。
         */
        boolean onInstallAppAndAppOnForeground(File file);
    }
}
